package org.nhindirect.stagent;

import java.security.cert.CertStore;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
import java.util.Collection;

import org.bouncycastle.cms.CMSSignedData;
import org.bouncycastle.cms.SignerId;
import org.bouncycastle.cms.SignerInformation;
import org.bouncycastle.cms.SignerInformationStore;
import org.nhindirect.stagent.cert.SingnerCertPair;

public class CryptoExtensions 
{
	
    public static boolean certSubjectContainsName(X509Certificate cert, String name)
    {
        if (name == null || name.length() == 0)
        {
            throw new IllegalArgumentException();
        }
        return cert.getSubjectDN().getName().contains(name);
    }	
	
    public static boolean matchName(X509Certificate cert, String name)
    {
        if (name == null || name.length() == 0)
        {
            throw new IllegalArgumentException();
        }

        String distinguishedName = "CN=" + name;
        return cert.getSubjectDN().getName().contains(distinguishedName);
    }


    public static SingnerCertPair findSignerByName(CMSSignedData signedData, String name)
    {
        if (name == null || name.length() == 0)
        {
            throw new IllegalArgumentException();
        }

        try
        {
	        CertStore               certs = signedData.getCertificatesAndCRLs("Collection", "BC");
	        SignerInformationStore  signers = signedData.getSignerInfos();
	        Collection<SignerInformation> c = signers.getSigners();
	        
	        for (SignerInformation signer : c)
	        {
	            Collection<? extends Certificate> certCollection = certs.getCertificates(signer.getSID());
	            if (certCollection != null && certCollection.size() > 0)
	            {
	            
	            	X509Certificate cert = (X509Certificate)certCollection.iterator().next();
	            	if (certSubjectContainsName(cert, name))
	            		return new SingnerCertPair(signer, cert); 
	            	
	            } 
	        }
        }
        catch (Exception e){}
        return null;
    }

    public static X509Certificate findCertByName(Collection<X509Certificate> certs, String name)
    {
    	for (X509Certificate cert : certs)
    	{
    		if (certSubjectContainsName(cert, name))
    			return cert;
    	}
    	
    	return null;
    }
    
    public static SingnerCertPair findSignerByCert(CMSSignedData signedData, X509Certificate searchCert)
    {

    	if (searchCert == null)
        {
            throw new IllegalArgumentException();
        }

        try
        {	                	
        	SignerInformationStore  signers = signedData.getSignerInfos();
	        Collection<SignerInformation> c = signers.getSigners();
	        
	        for (SignerInformation signer : c)
	        {
	        	SignerId signerId = signer.getSID();
	        	
	        	if (signerId.getIssuer().equals(searchCert.getIssuerX500Principal()) && 
	        			signerId.getSerialNumber().equals(searchCert.getSerialNumber()))
	        	{
	        		return new SingnerCertPair(signer, searchCert); 
	        	}	            			            	
	        }
        }
        catch (Exception e){}
        return null;
    }
    
    /*
    public static SignerInfo FindByThumbprint(this SignerInfoCollection signers, string thumbprint)
    {
        if (string.IsNullOrEmpty(thumbprint))
        {
            throw new ArgumentException();
        }

        return signers.Find(x => x.Certificate.Thumbprint == thumbprint);
    }
    
    public static bool DomainEquals(this MailAddress address, string domain)
    {
        if (string.IsNullOrEmpty(domain))
        {
            throw new ArgumentException();
        }
        
        return Protocol.Equals(address.Host, domain);
    }
    
    public static void Add(this MailAddressCollection addresses, IEnumerable<MailAddress> newAddresses)
    {
        foreach(MailAddress address in newAddresses)
        {
            addresses.Add(address);
        }
    }	
    */
}
